#include "PlayState.h"
#include "ResMgr.h"
#include "Board.h"
#include "Utils.h"
#include "GameTimer.h"
#include "GameOverState.h"
#include "StateMgr.h"
#include "GameUtils.h"
#include "ScoreBoard.h"
#include "Animation.h"
#include "AnimationSprite.h"
#include "Button.h"
#include "Texture.h"
#include "MainMenuState.h"
#include "Box.h"
#include "Level.h"
#include "GameCommonInfo.h"

PlayState* PlayState::instance = 0;

PlayState* PlayState::GetInstance()
{
	if(instance == 0)
	{
		instance = new PlayState();
	}
	return instance;
}


PlayState::PlayState()
{
	isSingleton = true;
	board=0;
	isPlaying = true;
}

PlayState::~PlayState()
{
	DELETE_SAFELY(gameTimer);
	DELETE_SAFELY(board);
	DELETE_SAFELY(scoreBoard);
	DELETE_SAFELY(asButton);
	DELETE_SAFELY(bHint);
	DELETE_SAFELY(bOption);

	ResMgr::GetInstance()->UnloadFruitBox();
}

void PlayState::Init()
{
	ResMgr* resMgr = ResMgr::GetInstance();
	resMgr->LoadFruitBox();

	board = new Board(0, 80, 40, 40);
	board->LoadMap(GameCommonInfo::GetInstance()->GetCurLevel());	//load map use data of current level
	board->SetBackground(resMgr->GetTexture(TID_COUNTRY_BACK));
	board->SetState(BS_INIT_DIAMOND);

	gameTimer = new GameTimer(240, X_GAME_TIMER, Y_GAME_TIMER, W_GAME_TIMER, H_GAME_TIMER);
	scoreBoard = new ScoreBoard(resMgr->GetTexture(TID_NUMBER), X_SCORE_BOARD, Y_SCORE_BOARD);

	asButton = new AnimationSprite();
	Animation* ani = new Animation(0);
	ani->GenerateAuto(resMgr->GetTexture(TID_BUTTON_IN_GAME),
		BUTTON_SPITE_WIDTH, BUTTON_SPRITE_HEIGHT, 2, 0, 7, 0);
	asButton->AddAnimation(ani);

	bHint = new Button(X_B_HINT, Y_B_HINT, BUTTON_SPITE_WIDTH, BUTTON_SPRITE_HEIGHT);
	bHint->SetImageForTouchUp(asButton, 0, 0);
	bHint->SetImageForTouchDown(asButton, 0, 1);

	bOption = new Button(X_B_OPTION, Y_B_OPTION, BUTTON_SPITE_WIDTH, BUTTON_SPRITE_HEIGHT);
	bOption->SetImageForTouchUp(asButton, 0, 2);
	bOption->SetImageForTouchDown(asButton, 0, 3);

	bNewGame = new Button(X_B_NEW_GAME, Y_B_NEW_GAME, BUTTON_SPITE_WIDTH, BUTTON_SPRITE_HEIGHT);
	bNewGame->SetImageForTouchUp(asButton, 0, 4);
	bNewGame->SetImageForTouchDown(asButton, 0, 5);

	bReturnToMainMenu = new Button(X_B_RETURN_TO_MAIN_MENU, Y_B_RETURN_TO_MAIN_MENU, BUTTON_SPITE_WIDTH, BUTTON_SPRITE_HEIGHT);
	bReturnToMainMenu->SetImageForTouchUp(asButton, 0, 6);
	bReturnToMainMenu->SetImageForTouchDown(asButton, 0, 7);

	optionBack = resMgr->GetTexture(TID_OPTION_BACK);
	headBack = resMgr->GetTexture(TID_HEAD_BACK);
	PRINT("Init PlayState success\n");

}

void PlayState::Update()
{
	if(isPlaying == true){
		board->Update();
		gameTimer->Update();
		if(gameTimer->IsTimeOut() == true)
			StateMgr::GetInstance()->SwitchState(new GameOverState());
		scoreBoard->Update();
	}
}

void PlayState::Render()
{
	board->Render();
	gameTimer->Render();
	scoreBoard->Render();
	bHint->Render();
	bOption->Render();
	headBack->Render(0, 0, 320.0f/W_HEAD_BACK_SPRITE, 320.0f/W_HEAD_BACK_SPRITE, 0, 1,  0.9);
	if(isPlaying == false)
	{
		optionBack->Render(X_BACK_OPT, Y_BACK_OPT, 1.0);
		bReturnToMainMenu->Render();
		bNewGame->Render();
	}
}

void PlayState::Exit()
{

}

void PlayState::TouchUp (int x, int y)
{
	if(isPlaying == true){
		board->TouchUp(x, y);
	}
	
	Button* bPressed = 0;

	if(bHint->GetIsTouchDown() == true) bPressed = bHint;
	if(bOption->GetIsTouchDown() == true) bPressed = bOption;
	
	if(isPlaying == false){
		if(bNewGame->GetIsTouchDown() == true) bPressed = bNewGame;
		if(bReturnToMainMenu->GetIsTouchDown() == true) bPressed = bReturnToMainMenu;
	}

	if(bPressed != 0)
	{
		bPressed->TouchUp();
		OnButtonClick(bPressed, BTE_TOUCH_UP);
	}
}

void PlayState::TouchDown (int x, int y)
{
	if(isPlaying == true){
		board->TouchDown(x, y);
	}

	//catch event for button
	Button* bPressed = 0;

	if(IsPointInRect(x, y, bHint->GetRect()))
		bPressed = bHint;
	if(IsPointInRect(x, y, bOption->GetRect()))
		bPressed = bOption;
	if(isPlaying == false)
	{
		if(IsPointInRect(x, y, bNewGame->GetRect()))
			bPressed = bNewGame;
		if(IsPointInRect(x, y, bReturnToMainMenu->GetRect()))
			bPressed = bReturnToMainMenu;
	}

	if(bPressed != 0)
	{
		bPressed->TouchDown();
		OnButtonClick(bPressed, BTE_TOUCH_DOWN);
	}
}

void PlayState::TouchMove (int x, int y)
{
	if(isPlaying == true){
		board->TouchMove(x, y);
	}
}

void PlayState::Reset(){
	ResMgr* resMgr = ResMgr::GetInstance();
	gameTimer->Reset();
	scoreBoard->Reset();

	board->Reset();
	board->LoadMap(GameCommonInfo::GetInstance()->GetCurLevel());
	board->SetBackground(resMgr->GetTexture(TID_COUNTRY_BACK));
	board->SetState(BS_INIT_DIAMOND);
}

void PlayState::OnButtonClick(Button* sender, int event)
{
	if(event == BTE_TOUCH_UP){
		if(sender == bOption)
		{
			isPlaying = !isPlaying;
		}else if(sender == bNewGame){
			Reset();
			isPlaying = true;
		}else if(sender == bReturnToMainMenu){
			StateMgr::GetInstance()->SwitchState(new MainMenuState());
		}
		else if(sender == bHint){
			board->Hint();
			gameTimer->DecreaseTime(TIME_DECREASE_WHEN_USE_HINT);
		}
	}
}

void PlayState::Destroy()
{
	PRINT("Destroy PlayState\n");
	DELETE_SAFELY(instance);
}